package com.ecoolex.chinadutyfree.retailer.admin.graphql;

import java.util.List;

import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.lang.NonNull;

import com.ecoolex.chinadutyfree.retailer.admin.core.AdminConstant;
import com.ecoolex.chinadutyfree.retailer.entity.GoodsCategory;
import com.ecoolex.chinadutyfree.retailer.entity.GoodsCategory.Column;
import com.ecoolex.chinadutyfree.retailer.entity.GoodsCategoryMarketing;
import com.ecoolex.chinadutyfree.retailer.pojo.AddGoodsCategoryDTO;
import com.ecoolex.chinadutyfree.retailer.pojo.EditGoodsCategoryDTO;
import com.ecoolex.chinadutyfree.retailer.pojo.QueryGoodsCategoryDTO;
import com.ecoolex.chinadutyfree.retailer.ws.GoodsService;
import com.ecoolex.framework.common.enums.ResultCode;
import com.ecoolex.framework.common.pojo.Page;
import com.ecoolex.framework.common.pojo.Pagination;
import com.ecoolex.framework.common.pojo.Sorting;
import com.ecoolex.framework.common.util.Assert;
import com.ecoolex.framework.common.util.BeanUtil;
import com.ecoolex.framework.common.util.Check;
import com.ecoolex.framework.modularize.api.auth.admin.AdminMemberAuthority;
import com.ecoolex.framework.modularize.api.auth.annotation.AdminAuthoritativeRegister;
import com.ecoolex.framework.modularize.api.service.storage.FileSize;
import com.ecoolex.framework.modularize.api.service.storage.MimeType;
import com.ecoolex.framework.modularize.api.service.storage.StorageInfo;
import com.ecoolex.framework.modularize.api.service.storage.StorageService;
import com.ecoolex.framework.modularize.api.service.storage.Upload;
import com.ecoolex.framework.modularize.api.service.storage.UploadLimit;
import com.ecoolex.framework.modularize.api.service.storage.UploadSource;
import com.ecoolex.framework.web.api.graphql2.annotation.GraphQL2Module;
import com.ecoolex.framework.web.api.graphql2.annotation.GraphQL2Module.Type;
import com.ecoolex.framework.web.api.graphql2.annotation.MutationField;
import com.ecoolex.framework.web.api.graphql2.annotation.QueryField;
import com.ecoolex.framework.web.api.graphql2.annotation.Source;
import com.ecoolex.framework.web.api.graphql2.annotation.TypeField;
import com.google.common.collect.Lists;


@GraphQL2Module(type = Type.Admin, description = "商品分类管理")
@AdminAuthoritativeRegister(parentKey = AdminConstant.AUTH_MODULE_KEY, key = GoodsCategoryGraphql.AUTH, name = "商品分类管理")
public class GoodsCategoryGraphql {

	public static final String AUTH = AdminConstant.AUTH_MODULE_KEY + "-GOODS-CATEGORY";

	@Reference
	private GoodsService goodsService;

	@Autowired
	private StorageService storageService;

	@TypeField(type = GoodsCategory.class, field = "parent", description = "父分类")
	public GoodsCategory parent(@Source GoodsCategory source) {
		if (Check.notNullAndGtZero(source.getParentCategoryId())) {
			return goodsService.getCategoryById(source.getParentCategoryId());
		}
		return null;
	}

	@TypeField(type = GoodsCategory.class, field = "child", description = "子分类列表")
	public List<GoodsCategory> child(@Source GoodsCategory source, Boolean isShow) {
		return goodsService.queryCategoryByParentId(source.getCategoryId(), isShow);
	}

	@TypeField(type = GoodsCategory.class, field = "icon", description = "Icon")
	public StorageInfo icon(@Source GoodsCategory source) {
		return storageService.get(source.getIcon());
	}

	@TypeField(type = GoodsCategory.class, field = "image", description = "图片")
	public StorageInfo image(@Source GoodsCategory source) {
		return storageService.get(source.getImage());
	}

	@TypeField(type = GoodsCategory.class, field = "banner", description = "广告位图片")
	public StorageInfo banner(@Source GoodsCategory source) {
		return storageService.get(source.getBanner());
	}

	@TypeField(type = GoodsCategory.class, field = "canSetShow", description = "是否能设置展示")
	public Boolean canSetShow(@Source GoodsCategory source) {
		return !source.getIsShow();
	}

	@TypeField(type = GoodsCategory.class, field = "canSetHide", description = "是否能设置隐藏")
	public Boolean canSetHide(@Source GoodsCategory source, AdminMemberAuthority user) {
		return source.getIsShow();
	}
	
	@TypeField(type = GoodsCategory.class, field = "existCategoryMarketingConfig", description = "是否存在于分类推荐配置中")
	public boolean existCategoryMarketingConfig(@Source GoodsCategory source) {
		GoodsCategoryMarketing marketing = goodsService.getGoodsCategoryMarketingByCategoryId(source.getCategoryId());
		return marketing == null ? false : true;
	}

	private static final String AUTH_GET = AUTH + "-GET";

	@QueryField(field = "goodsCategory", description = "获取商品分类详情")
	@AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_GET, name = "获取商品分类详情")
	public GoodsCategory get(@NonNull Integer categoryId, AdminMemberAuthority user) {
		user.assertLogin();
		return goodsService.getCategoryById(categoryId);
	}

	private static final String AUTH_QUERY = AUTH + "-QUERY";

	@QueryField(field = "goodsCategoryList", description = "查询商品分类列表")
	@AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_QUERY, name = "查询商品分类列表")
	public Pagination<GoodsCategory> queryCategory(@NonNull QueryGoodsCategoryDTO query, @NonNull Sorting[] sorts, @NonNull Page page, AdminMemberAuthority user) {
		user.assertLogin();
		return goodsService.queryCategory(query, sorts, page);
	}

	@QueryField(field = "goodsBrandListByParentId", description = "根据父分类查询子分类列表")
	public List<GoodsCategory> query(@NonNull Integer parentCategoryId, Boolean isShow, AdminMemberAuthority user) {
		user.assertLogin();
		return goodsService.queryCategoryByParentId(parentCategoryId, isShow);
	}

	@MutationField(field = "uploadGoodsCategoryIcon", description = { "上传商品分类Icon" })
	public StorageInfo uploadGoodsCategoryIcon(@NonNull Upload request, AdminMemberAuthority user) {
		if (!user.auth(AUTH_ADD) && !user.auth(AUTH_EDIT)) {
            user.notAuthority();
        }
        UploadSource uploadSource = new UploadSource("GoodsCategory", "Icon");
        UploadLimit uploadLimit = new UploadLimit();
        uploadLimit.setMaxSize(FileSize.MB.byteLength(2));
        uploadLimit.setAllowMimeType(MimeType.IMAGE.commons());

        return storageService.upload(request, uploadSource, uploadLimit);
	}

	@MutationField(field = "uploadGoodsCategoryImage", description = { "上传商品分类图片" })
	public StorageInfo uploadGoodsCategoryImage(@NonNull Upload request, AdminMemberAuthority user) {
		if (!user.auth(AUTH_ADD) && !user.auth(AUTH_EDIT)) {
            user.notAuthority();
        }
        UploadSource uploadSource = new UploadSource("GoodsCategory", "Image");
        UploadLimit uploadLimit = new UploadLimit();
        uploadLimit.setMaxSize(FileSize.MB.byteLength(2));
        uploadLimit.setAllowMimeType(MimeType.IMAGE.commons());

        return storageService.upload(request, uploadSource, uploadLimit);
	}

	@MutationField(field = "uploadGoodsCategoryBanner", description = { "上传商品分类广告位图片" })
	public StorageInfo uploadGoodsCategoryBanner(@NonNull Upload request, AdminMemberAuthority user) {
		if (!user.auth(AUTH_ADD) && !user.auth(AUTH_EDIT)) {
            user.notAuthority();
        }
        UploadSource uploadSource = new UploadSource("GoodsCategory", "Banner");
        UploadLimit uploadLimit = new UploadLimit();
        uploadLimit.setMaxSize(FileSize.MB.byteLength(2));
        uploadLimit.setAllowMimeType(MimeType.IMAGE.commons());

        return storageService.upload(request, uploadSource, uploadLimit);
	}

	private static final String AUTH_ADD = AUTH + "-ADD";

	@MutationField(field = "addGoodsCategory", description = "添加商品分类")
	@AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_ADD, name = "添加商品分类")
	public GoodsCategory add(@NonNull AddGoodsCategoryDTO add, AdminMemberAuthority user) {
		user.assertAuth(AUTH_ADD);
		return goodsService.addCategory(add, user.userName());
	}

	private static final String AUTH_EDIT = AUTH + "-EDIT";

	@MutationField(field = "editGoodsCategory", description = "编辑商品分类")
	@AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_EDIT, name = "编辑商品分类")
	public GoodsCategory edit(@NonNull EditGoodsCategoryDTO edit, AdminMemberAuthority user) {
		user.assertAuth(AUTH_EDIT);
		GoodsCategory old = goodsService.getCategoryById(edit.getCategoryId());
		Assert.isTrue(Check.notNull(old), ResultCode.VERIFY.build(1), "分类不存在");
		BeanUtil.copy(edit,
			old,
			Lists.newArrayList(Column.level,
				Column.isShow,
				Column.deleted,
				Column.createUser,
				Column.createTime).stream().map(Column::getJavaProperty).toArray(String[]::new));
		return goodsService.updateCategory(old, user.userName());
	}

	private static final String AUTH_DEL = AUTH + "-DEL";

	@MutationField(field = "delGoodsCategory", description = "删除商品分类")
	@AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_DEL, name = "删除商品分类")
	public Boolean del(@NonNull Integer categoryId, AdminMemberAuthority user) {
		user.assertAuth(AUTH_DEL);
		GoodsCategory record = goodsService.getCategoryById(categoryId);
		Assert.isTrue(Check.notNull(record), ResultCode.VERIFY.build(1), "分类不存在");
		goodsService.deleteCategory(record, user.userName());
		return true;
	}

	private static final String AUTH_SHOW = AUTH + "-SHOW";

	@MutationField(field = "setShowGoodsCategory", description = "设置展示商品分类")
	@AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_SHOW, name = "设置展示商品分类")
	public GoodsCategory show(@NonNull Integer categoryId, AdminMemberAuthority user) {
		user.assertAuth(AUTH_SHOW);
		GoodsCategory record = goodsService.getCategoryById(categoryId);
		Assert.isTrue(Check.notNull(record), ResultCode.VERIFY.build(1), "分类不存在");
		return goodsService.showCategory(record, user.userName());
	}

	private static final String AUTH_HIDE = AUTH + "-HIDE";

	@MutationField(field = "setHideGoodsCategory", description = "设置隐藏商品分类")
	@AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_HIDE, name = "设置隐藏商品分类")
	public GoodsCategory hide(@NonNull Integer categoryId, AdminMemberAuthority user) {
		user.assertAuth(AUTH_HIDE);
		GoodsCategory record = goodsService.getCategoryById(categoryId);
		Assert.isTrue(Check.notNull(record), ResultCode.VERIFY.build(1), "分类不存在");
		return goodsService.hideCategory(record, user.userName());
	}
}

